import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:meco/common/index.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'dart:math';

// Video source type
enum VideoSource { all, favorites, likes }

class VideoDetailController extends GetxController
    implements VideoInteractionObserver, VideoDeleteObserver {
  VideoDetailController();

  // Page controller - for page sliding
  late PageController pageController;

  // Video list
  final RxList<RecommendedVideo> videos = <RecommendedVideo>[].obs;

  // Current video index
  final RxInt currentIndex = 0.obs;

  // Video source type
  final Rx<VideoSource> videoSource = VideoSource.all.obs;

  // Loading status
  final RxBool isLoading = true.obs;

  // Favorite status
  final RxMap<int, bool> favoriteStatus = <int, bool>{}.obs;

  // Like status
  final RxMap<int, bool> likeStatus = <int, bool>{}.obs;

  // Favorite counts
  final RxMap<int, int> favoriteCounts = <int, int>{}.obs;

  // Like counts
  final RxMap<int, int> likeCounts = <int, int>{}.obs;

  // Repositories
  final RecommendedVideoRepository _videoRepository =
      RecommendedVideoRepository();
  final VideoInteractionRepository _videoInteractionRepository =
      VideoInteractionRepository();

  @override
  void onInit() {
    super.onInit();

    // Register as observer for video interactions
    VideoInteractionRepository.addObserver(this);
    // Register as observer for video deletions
    RecommendedVideoRepository.addObserver(this);

    // Initialize page controller
    pageController = PageController();

    // Parse route arguments
    _parseArguments();

    // Load video data
    _loadVideos();
  }

  @override
  void onClose() {
    // Remove observers when controller is closed
    VideoInteractionRepository.removeObserver(this);
    RecommendedVideoRepository.removeObserver(this);
    pageController.dispose();
    super.onClose();
  }

  // Parse route arguments
  void _parseArguments() {
    final arguments = Get.arguments;

    if (arguments != null) {
      // Get video source type
      if (arguments.containsKey('source')) {
        final sourceStr = arguments['source'] as String;
        if (sourceStr == 'favorites') {
          videoSource.value = VideoSource.favorites;
        } else if (sourceStr == 'likes') {
          videoSource.value = VideoSource.likes;
        }
      }

      // Get initial video index
      if (arguments.containsKey('initialIndex')) {
        currentIndex.value = arguments['initialIndex'] as int;
        print('Setting initial index to: ${currentIndex.value}');
      }
    }
  }

  // Load video list data
  Future<void> _loadVideos() async {
    isLoading.value = true;

    try {
      final UserService userService = Get.find<UserService>();
      final int? userId = userService.currentUser.value?.id;

      if (userId == null) {
        // Only load recommended videos when not logged in
        await _loadAllVideos();
      } else {
        // Load videos based on source
        switch (videoSource.value) {
          case VideoSource.all:
            await _loadAllVideos();
            break;
          case VideoSource.favorites:
            await _loadFavoriteVideos(userId);
            break;
          case VideoSource.likes:
            await _loadLikedVideos(userId);
            break;
        }
      }

      // Load video interaction status
      if (userId != null && videos.isNotEmpty) {
        await _loadInteractionStatus(userId);
      }

      // Jump to the specified index if valid
      if (currentIndex.value >= 0 && currentIndex.value < videos.length) {
        // Use jumpToPage instead of animateToPage to avoid animation when first entering
        WidgetsBinding.instance.addPostFrameCallback((_) {
          if (pageController.hasClients) {
            pageController.jumpToPage(currentIndex.value);
          }
        });
      } else if (videos.isNotEmpty) {
        // Reset to first video if index is invalid
        currentIndex.value = 0;
      }
    } catch (e) {
      print('Failed to load video data: $e');
      EasyLoading.showError('Failed to load videos');
    } finally {
      isLoading.value = false;
    }
  }

  // Load all videos
  Future<void> _loadAllVideos() async {
    try {
      final allVideos = await _videoRepository.getAllRecommendedVideos();

      // If videos from database don't have valid URLs, add some demo videos
      if (allVideos.isEmpty || allVideos.every((v) => v.videoUrl.isEmpty)) {
        print('Using demo video data');
        videos.value = _getDemoVideos();
      } else {
        // Ensure all videos have valid URLs
        videos.value = allVideos.where((v) => v.videoUrl.isNotEmpty).toList();
        if (videos.isEmpty) {
          videos.value = _getDemoVideos();
        }
      }
    } catch (e) {
      print('Failed to load videos, using demo data: $e');
      videos.value = _getDemoVideos();
    }
  }

  // Get demo videos
  List<RecommendedVideo> _getDemoVideos() {
    return [
      RecommendedVideo(
        id: 1,
        description:
            'Sample Video 1: This is a short video example showcasing different exciting moments.',
        thumbnailUrl: 'assets/images/video_thumb1.jpg',
        videoUrl: 'assets/videos/video1.mp4',
      ),
      RecommendedVideo(
        id: 2,
        description:
            'Sample Video 2: Beautiful natural scenery combined with moving music for an audiovisual feast.',
        thumbnailUrl: 'assets/images/video_thumb2.jpg',
        videoUrl: 'assets/videos/video2.mp4',
      ),
      RecommendedVideo(
        id: 3,
        description:
            'Sample Video 3: Creative short film showcasing the perfect combination of art and technology.',
        thumbnailUrl: 'assets/images/video_thumb3.jpg',
        videoUrl: 'assets/videos/video3.mp4',
      ),
      RecommendedVideo(
        id: 4,
        description:
            'Sample Video 4: Recording beautiful moments in life, sharing joy and emotion.',
        thumbnailUrl: 'assets/images/video_thumb4.jpg',
        videoUrl: 'assets/videos/video4.mp4',
      ),
    ];
  }

  // Load favorite videos
  Future<void> _loadFavoriteVideos(int userId) async {
    try {
      final favoriteVideos = await _videoInteractionRepository
          .getFavoritedVideos(userId);

      // Ensure all videos have valid URLs
      if (favoriteVideos.isEmpty ||
          favoriteVideos.every((v) => v.videoUrl.isEmpty)) {
        // If no favorite videos or favorite videos have invalid URLs, use demo data
        videos.value = _getDemoVideos();
      } else {
        videos.value =
            favoriteVideos.where((v) => v.videoUrl.isNotEmpty).toList();
        if (videos.isEmpty) {
          videos.value = _getDemoVideos();
        }
      }
    } catch (e) {
      print('Failed to load favorite videos, using demo data: $e');
      EasyLoading.showError('Failed to load favorite videos');
      videos.value = _getDemoVideos();
    }
  }

  // Load liked videos
  Future<void> _loadLikedVideos(int userId) async {
    try {
      final likedVideos = await _videoInteractionRepository.getLikedVideos(
        userId,
      );

      // Ensure all videos have valid URLs
      if (likedVideos.isEmpty || likedVideos.every((v) => v.videoUrl.isEmpty)) {
        // If no liked videos or liked videos have invalid URLs, use demo data
        videos.value = _getDemoVideos();
      } else {
        videos.value = likedVideos.where((v) => v.videoUrl.isNotEmpty).toList();
        if (videos.isEmpty) {
          videos.value = _getDemoVideos();
        }
      }
    } catch (e) {
      print('Failed to load liked videos, using demo data: $e');
      EasyLoading.showError('Failed to load liked videos');
      videos.value = _getDemoVideos();
    }
  }

  // Load video interaction status
  Future<void> _loadInteractionStatus(int userId) async {
    for (var video in videos) {
      if (video.id == null) continue;

      // Load favorite status
      final isFavorite = await _videoInteractionRepository.hasFavorited(
        userId,
        video.id!,
      );
      favoriteStatus[video.id!] = isFavorite;

      // Load like status
      final isLiked = await _videoInteractionRepository.hasLiked(
        userId,
        video.id!,
      );
      likeStatus[video.id!] = isLiked;

      // Get video info including favorite and like counts
      final videoDetail = await _videoRepository.getRecommendedVideoById(
        video.id!,
      );
      if (videoDetail != null) {
        favoriteCounts[video.id!] = videoDetail.favoriteCount ?? 0;
        likeCounts[video.id!] = videoDetail.likeCount ?? 0;
      }
    }
  }

  // Toggle favorite status
  Future<void> toggleFavorite() async {
    final UserService userService = Get.find<UserService>();

    // Check login status
    if (!userService.isLoggedIn.value) {
      userService.checkLoginThenExecute(
        loginRequiredMessage: 'Please login to favorite videos',
        onLoggedIn: () => toggleFavorite(),
      );
      return;
    }

    final userId = userService.currentUser.value!.id!;
    final currentVideo = getCurrentVideo();
    final videoId = currentVideo?.id;

    if (videoId == null) return;

    final isFavorited = favoriteStatus[videoId] ?? false;

    try {
      if (isFavorited) {
        // Unfavorite
        await _videoInteractionRepository.unfavoriteVideo(userId, videoId);
        // 状态更新会通过观察者回调处理，不需要在这里更新
      } else {
        // Add favorite
        await _videoInteractionRepository.favoriteVideo(userId, videoId);
        // 状态更新会通过观察者回调处理，不需要在这里更新
      }
      // UI更新会通过观察者回调触发
    } catch (e) {
      print('Failed to update favorite: $e');
      EasyLoading.showError('Failed to update favorite');
    }
  }

  // Toggle like status
  Future<void> toggleLike() async {
    final UserService userService = Get.find<UserService>();

    // Check login status
    if (!userService.isLoggedIn.value) {
      userService.checkLoginThenExecute(
        loginRequiredMessage: 'Please login to like videos',
        onLoggedIn: () => toggleLike(),
      );
      return;
    }

    final userId = userService.currentUser.value!.id!;
    final currentVideo = getCurrentVideo();
    final videoId = currentVideo?.id;

    if (videoId == null) return;

    final isLiked = likeStatus[videoId] ?? false;

    try {
      if (isLiked) {
        // Unlike
        await _videoInteractionRepository.unlikeVideo(userId, videoId);
        // 状态更新会通过观察者回调处理，不需要在这里更新
      } else {
        // Add like
        await _videoInteractionRepository.likeVideo(userId, videoId);
        // 状态更新会通过观察者回调处理，不需要在这里更新
      }
      // UI更新会通过观察者回调触发
    } catch (e) {
      print('Failed to update like: $e');
      EasyLoading.showError('Failed to update like');
    }
  }

  // Get current video
  RecommendedVideo? getCurrentVideo() {
    if (videos.isEmpty || currentIndex.value >= videos.length) {
      return null;
    }
    return videos[currentIndex.value];
  }

  // Handle page change
  void onPageChanged(int index) {
    print('Page changed to index: $index');
    // Only update if the index has actually changed
    if (currentIndex.value != index) {
      currentIndex.value = index;

      // Ensure the video at the new index is played automatically
      // This is handled by the VideoPlayerWidget's didUpdateWidget method
      // which checks if isPlaying changed and calls _updatePlayingState
    }
  }

  // Report video
  void reportVideo(RecommendedVideo video) {
    ReportBottomSheet.show(
      onReport: (reason) async {
        // 这里可以实现实际的举报逻辑，如发送到服务器
        print('举报视频: ${video.id}, 原因: ${reason.toString()}');

        // 模拟API调用
        await Future.delayed(Duration(seconds: 1));

        // 删除视频
        try {
          if (video.id != null) {
            // 使用Repository删除视频，这将通知所有观察者
            final success = await _videoRepository.deleteVideo(video.id!);

            if (success) {
              EasyLoading.showSuccess('你将不会再看到此内容');

              // 如果当前没有视频了，返回上一页
              if (videos.isEmpty) {
                Future.delayed(Duration(seconds: 1), () {
                  Get.back();
                });
              }
            } else {
              EasyLoading.showError('举报失败，请稍后再试');
            }
          }
        } catch (e) {
          print('删除视频失败: $e');
          EasyLoading.showError('举报失败，请稍后再试');
        }

        return true;
      },
    );
  }

  // Implement VideoInteractionObserver interface
  @override
  void onVideoLikeStatusChanged(int userId, int videoId, bool isLiked) {
    // Update like status for the specific video
    if (likeStatus.containsKey(videoId)) {
      likeStatus[videoId] = isLiked;

      // Update like count
      if (likeCounts.containsKey(videoId)) {
        if (isLiked) {
          likeCounts[videoId] = (likeCounts[videoId] ?? 0) + 1;
        } else {
          likeCounts[videoId] = max(0, (likeCounts[videoId] ?? 1) - 1);
        }
      }

      // Update UI
      update(['video_detail']);
    }

    // Update the video in the list if it exists
    for (int i = 0; i < videos.length; i++) {
      if (videos[i].id == videoId) {
        int newCount;
        if (isLiked) {
          newCount = (videos[i].likeCount ?? 0) + 1;
        } else {
          newCount = max(0, (videos[i].likeCount ?? 1) - 1);
        }
        videos[i] = videos[i].copyWith(likeCount: newCount);
        break;
      }
    }
  }

  @override
  void onVideoFavoriteStatusChanged(int userId, int videoId, bool isFavorited) {
    // Update favorite status for the specific video
    if (favoriteStatus.containsKey(videoId)) {
      favoriteStatus[videoId] = isFavorited;

      // Update favorite count
      if (favoriteCounts.containsKey(videoId)) {
        if (isFavorited) {
          favoriteCounts[videoId] = (favoriteCounts[videoId] ?? 0) + 1;
        } else {
          favoriteCounts[videoId] = max(0, (favoriteCounts[videoId] ?? 1) - 1);
        }
      }

      // Update UI
      update(['video_detail']);
    }

    // Update the video in the list if it exists
    for (int i = 0; i < videos.length; i++) {
      if (videos[i].id == videoId) {
        int newCount;
        if (isFavorited) {
          newCount = (videos[i].favoriteCount ?? 0) + 1;
        } else {
          newCount = max(0, (videos[i].favoriteCount ?? 1) - 1);
        }
        videos[i] = videos[i].copyWith(favoriteCount: newCount);
        break;
      }
    }

    // If we're in favorites view and a video was unfavorited, we might need to remove it
    if (!isFavorited && videoSource.value == VideoSource.favorites) {
      // Check if the unfavorited video is in our list
      int videoIndex = videos.indexWhere((v) => v.id == videoId);
      if (videoIndex != -1) {
        // If this is the current video, move to the next one before removing
        if (videoIndex == currentIndex.value) {
          // If it's the last video, move to the previous one
          if (videoIndex == videos.length - 1 && videoIndex > 0) {
            onPageChanged(videoIndex - 1);
          }
          // Otherwise move to the next one
          else if (videoIndex < videos.length - 1) {
            onPageChanged(videoIndex + 1);
          }
        }

        // Remove the video from the list after a short delay to allow the page transition
        Future.delayed(Duration(milliseconds: 300), () {
          videos.removeAt(videoIndex);

          // If no videos left, go back
          if (videos.isEmpty) {
            Get.back();
            EasyLoading.showInfo('No more favorite videos');
          }

          update(['video_detail']);
        });
      }
    }

    // Similarly for likes view
    if (videoSource.value == VideoSource.likes &&
        !(likeStatus[videoId] ?? false)) {
      // Check if the unliked video is in our list
      int videoIndex = videos.indexWhere((v) => v.id == videoId);
      if (videoIndex != -1) {
        // If this is the current video, move to the next one before removing
        if (videoIndex == currentIndex.value) {
          // If it's the last video, move to the previous one
          if (videoIndex == videos.length - 1 && videoIndex > 0) {
            onPageChanged(videoIndex - 1);
          }
          // Otherwise move to the next one
          else if (videoIndex < videos.length - 1) {
            onPageChanged(videoIndex + 1);
          }
        }

        // Remove the video from the list after a short delay to allow the page transition
        Future.delayed(Duration(milliseconds: 300), () {
          videos.removeAt(videoIndex);

          // If no videos left, go back
          if (videos.isEmpty) {
            Get.back();
            EasyLoading.showInfo('No more liked videos');
          }

          update(['video_detail']);
        });
      }
    }
  }

  // 实现VideoDeleteObserver接口
  @override
  void onVideoDeleted(int videoId) {
    // 从列表中移除视频
    final index = videos.indexWhere((v) => v.id == videoId);
    if (index != -1) {
      videos.removeAt(index);

      // 如果删除的是当前视频，跳转到下一个或上一个视频
      if (index == currentIndex.value) {
        if (videos.isEmpty) {
          // 如果没有视频了，返回上一页
          Future.delayed(Duration(seconds: 1), () {
            Get.back();
          });
        } else {
          // 如果还有视频，跳转到下一个或上一个视频
          final newIndex = min(index, videos.length - 1);
          currentIndex.value = newIndex;
          pageController.jumpToPage(newIndex);
        }
      } else {
        // 如果删除的不是当前视频，更新当前索引
        if (index < currentIndex.value) {
          currentIndex.value--;
          pageController.jumpToPage(currentIndex.value);
        }
      }

      // 更新UI
      update(['video_detail']);
    }
  }
}
